﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.IO;
using System.Runtime.Serialization;

using System.Xml;
using System.Xml.Serialization;

using Optimization.Experiment;
//using Optimization.StandardProblems;
using Optimization.StandardSolvers;
using Optimization.Utilities;

using System.Reflection;
using System.Reflection.Emit;

using MDProblems;

namespace Tests
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        string pName0 = "MDProblems.DUB_MA_NORM_LOG_201307, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
        string pName1 = "MDProblems.DUB_MA_NORM_LIN_201307, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";

        string[] pNames = new string[]
        {
            "MDProblems.DUB_MA_NORM_LOG_201307, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MA_LIN_201307, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MA_LOG_201307, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MA_NORM_LIN_201307, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MD_NORM_LOG_201307, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MD_LIN_201307, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MD_LOG_201307, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MD_NORM_LIN_201307, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",

            "MDProblems.DUB_MA_NORM_LOG_201308, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MA_LIN_201308, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MA_LOG_201308, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MA_NORM_LIN_201308, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MD_NORM_LOG_201308, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MD_LIN_201308, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MD_LOG_201308, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
            "MDProblems.DUB_MD_NORM_LIN_201308, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
        };

        private void button1_Click(object sender, EventArgs e)
        {
            foreach (string pName in pNames)
            {
                Type problemType = Type.GetType(pName);

                IProblem problem = Activator.CreateInstance(problemType) as IProblem;

                textBox1.Text += "\r\n" + problem.GetType().AssemblyQualifiedName;

                double[] Values1 = new double[1000];
                for (int i = 0; i < Values1.Length; i++)
                {
                    Vector rndSolution = problem.RandomSolution();
                    Values1[i] = Math.Log10(rndSolution[0]);
                }

                double min = Values1[0];
                double max = Values1[0];

                for (int i = 0; i < Values1.Length; i++)
                {
                    if (min > Values1[i])
                        min = Values1[i];
                    if (max < Values1[i])
                        max = Values1[i];
                }

                double minmax = max - min;

                int[] counters = new int[10];
                for (int i = 0; i < Values1.Length; i++)
                {
                    if (double.IsNaN(Values1[i]))
                        continue;

                    int category = (int)((Values1[i] - min) / minmax * 10);
                    if (category == 10)
                        category = 9;
                    counters[category]++;
                }

                for (int i = 0; i < counters.Length; i++)
                {
                    textBox1.Text += "\r\n" + i.ToString() + "\t" + counters[i].ToString();
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Vector v = new Vector(1.5, 0);
            Type t = typeof(Vector);

            XmlSerializer ser = new XmlSerializer(t);
            MemoryStream ms = new MemoryStream();
            ser.Serialize(ms, v);

            textBox1.Text = ASCIIEncoding.UTF8.GetString(ms.GetBuffer());
            
            
            //Type problemType = Type.GetType("MDProblems.DUB_MA_LIN_201307, MDProblems, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
        }

    }

    class Sphere2 : IProblem
    {

        virtual public int GetDim()
        {
            return 2;
        }

        public double Evaluate(Optimization.Utilities.Vector v)
        {
            double result = 0;
            for (int i = 0; i < v.Length; i++)
                result += v[i] * v[i];
            return result;
        }

        public void GetBounds(out Optimization.Utilities.Vector mins, out Optimization.Utilities.Vector maxs)
        {
            mins = -10 * Vector.One(GetDim());
            maxs = 10 * Vector.One(GetDim());
        }

        public bool IsFeasible(Optimization.Utilities.Vector v)
        {
            return true;
        }

        public Optimization.Utilities.Vector RandomSolution()
        {
            Vector result = Vector.Random(GetDim(), -10, 10);
            return result;
        }
    }

    class Sphere3 : Sphere2
    {
        public override int GetDim()
        {
            return 3;
        }
    }

    class Sphere4 : Sphere2
    {
        public override int GetDim()
        {
            return 4;
        }
    }

    class Sphere5 : Sphere2
    {
        public override int GetDim()
        {
            return 5;
        }
    }
}
